//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#ifndef __ELASTOS_BSP_H__
#define __ELASTOS_BSP_H__

#include <bsp/bspcfg.h>
#include <kcrt.h>
#include <util.h>

#define BYTE    unsigned char
#define UCHAR   unsigned char
#define UINT    unsigned int
#define ULONG   unsigned long
#define USHORT  unsigned short
#define WORD    unsigned short
#define DWORD   unsigned long
#define BOOL    int

// the range of a MemoryRegion presents is [Base, Limit)
typedef struct MemoryRegion {
    uint_t      uBasePageNo;
    uint_t      uLimitPageNo;
} MemoryRegion, MemoryZone, MemoryHole;

const uint_t c_uMaxLengthOfBootModuleName = 19;

typedef struct BootModule {
    char            szName[c_uMaxLengthOfBootModuleName + 1];
    uint_t          size;
    MemoryRegion    region;
} BootModule;

typedef enum ComPort {
    ComPort1    = 1,
    ComPort2    = 2,
    ComPort3    = 3,
    ComPort4    = 4,
} ComPort;

typedef enum ComPortParity {
    ComPortParity_No            = 0,
    ComPortParity_Odd           = 1,
    ComPortParity_Even          = 2,
    ComPortParity_Mark          = 3,
    ComPortParity_Space         = 4,

    ComPortParity_Default       = ComPortParity_No,
} ComPortParity;

typedef enum ComPortStopBits {
    ComPortStopBits_One         = 0,
    ComPortStopBits_One5        = 1,
    ComPortStopBits_Two         = 2,

    ComPortStopBits_Default     = ComPortStopBits_One,
} ComPortStopBits;

typedef enum ComPortByteSize {
    ComPortByteSize_5           = 5,
    ComPortByteSize_6           = 6,
    ComPortByteSize_7           = 7,
    ComPortByteSize_8           = 8,

    ComPortByteSize_Default     = ComPortByteSize_8,
} ComPortByteSize;

typedef struct ComPortSettings {
    uint_t              uBaudRate;
    ComPortByteSize     byteSize;
    ComPortParity       parity;
    ComPortStopBits     stopBits;
} ComPortSettings;

typedef uint8_t     irq_t;

#ifdef _x86
typedef uint32_t    irqs_t;
#elif defined(_arm)
typedef uint64_t    irqs_t;
#elif defined(_mips)
typedef uint8_t     irqs_t;
#else
#error unknown architecture
#endif // _x86

typedef uint8_t     ipl_t;

enum {
    IPL0        = 0,
    IPL1        = 1,
    IPL2        = 2,
    IPL3        = 3,
    IPL4        = 4,
    IPL5        = 5,
    IPL6        = 6,
    IPL7        = 7,
    IPL8        = 8,
    IPL9        = 9,
    IPL10       = 10,
    IPL11       = 11,
    IPL12       = 12,
    IPL13       = 13,
    IPL14       = 14,
    IPL15       = 15,
    IPL16       = 16,
    IPL17       = 17,
    IPL18       = 18,
    IPL19       = 19,
    IPL20       = 20,
    IPL21       = 21,
    IPL22       = 22,
    IPL23       = 23,
    IPL24       = 24,
    IPL25       = 25,
    IPL26       = 26,
    IPL27       = 27,
    IPL28       = 28,
    IPL29       = 29,
    IPL30       = 30,
    IPL31       = 31,
    IPL_Base    = 32
};

#define MAX_IPL     IPL0
#define MIN_IPL     IPL31

typedef struct RTCTime {
    uint_t uYear;
    uint_t uMonth;
    uint_t uDate;
    uint_t uHours;
    uint_t uMinutes;
    uint_t uSeconds;
} RTCTime;

//
// Bsp global variables for Kernel
//
typedef struct BspGlobals
{
    // Descriptions
    char                     *szCpuDescription;
    char                     *szBoardDescription;

    // Physical memory base
    physaddr_t               paKernelPhysBase;
    physaddr_t               paKernelImagePhysBase;

    // Zones and Holes
    MemoryZone               *pMemoryZones;
    uint_t                   uNumberOfMemoryZones;

    MemoryHole               *pMemoryHoles;
    uint_t                   uNumberOfMemoryHoles;

    uint_t                   uDmaPreferredZoneNo;
    uint_t                   uKernelPreferredZoneNo;
    uint_t                   uUserPreferredZoneNo;

    MemoryRegion             regionOfInitStack;

    // Boot Modules
    BootModule               *pBootModules;
    uint_t                   uNumberOfBootModules;
    MemoryRegion             regionOfBootModules;

    char                     *szBootCommandLine;

    // Programmable interrupt controller
    uint32_t                 uIrqBase;
    uint_t                   uNumberOfIrqs;

    // Programmable interval timer
    irq_t                    irqOfPIT;
    ipl_t                    iplOfPIT;
} BspGlobals;

EXTERN_C BspGlobals bsp;

//
//  OS startup entry
//
EXTERN_C void mainCRTStartup();

//
// Devices
//
// Machine
EXTERN_C void CDECL BspIdle();
EXTERN_C void CDECL BspHalt();
EXTERN_C void CDECL BspReboot();

// Speaker
EXTERN_C void CDECL BspBeep();

// Communications ports
EXTERN_C bool_t CDECL BspSetupComPort(
        ComPort comPort, const ComPortSettings *pSettings);
EXTERN_C bool_t CDECL BspReadComPort(ComPort comPort, uint8_t *pu8Data);
EXTERN_C bool_t CDECL BspWriteComPort(ComPort comPort, uint8_t u8Data);
EXTERN_C bool_t CDECL BspTryReadComPort(
    ComPort comPort, uint8_t *pu8Data, uint_t uTimes);

// Programmable interrupt controller
EXTERN_C irqs_t CDECL BspGetIrqs();

EXTERN_C void CDECL BspMaskIrqs(irqs_t irqs, bool_t bEnable);
EXTERN_C void CDECL BspMaskAllIrqs(bool_t bEnable);

EXTERN_C void CDECL BspAcknowledgeIrq(irq_t irq);

EXTERN_C void   CDECL BspReloadPIT();
EXTERN_C uint_t CDECL BspGetPITTime();      // unit: NS

EXTERN_C void   CDECL BspGetRTCTime(RTCTime *pRTCTime);
EXTERN_C void   CDECL BspSetRTCTime(const RTCTime *pRTCTime);

//
// Console
//
EXTERN_C void CDECL BspWriteConsole(const char *szMessage);

//
// Kernel global variables for Bsp
//
typedef struct KrnGlobals
{
    virtaddr_t      vaKernelVirtBase;

    uint_t          uTickRate;
} KrnGlobals;

EXTERN_C KrnGlobals krn;

// Kernel routines
EXTERN_C DECL_CODEINIT void CDECL KrnSetup(
        physaddr_t paKernelPhysBase, physaddr_t paKernelImagePhysBase,
        physaddr_t paMemoryMappedIoBase, physaddr_t paMemoryMappedIoLimit,
        int reserved1, int reserved2);
EXTERN_C DECL_CODEINIT bool_t CDECL KrnInitialize();
EXTERN_C DECL_CODEINIT void   CDECL KrnStartup();

#endif //__ELASTOS_BSP_H__
